package core

import (
  "context"
  "fmt"
  "go.uber.org/zap"
  "livefind/global"
  "livefind/initialize"
  "livefind/utils/logger"
  "net/http"
  "os"
  "os/signal"
  "syscall"
  "time"
)

type server interface {
	ListenAndServe() error
	Shutdown(ctx context.Context) error
}

func RunWindowsServer() {
	if global.GVA_CONFIG.System.UseMultipoint {
		// 初始化redis服务
		initialize.Redis()
	}
	Router := initialize.Routers()
	Router.Static("/form-generator", "./resource/page")

	address := fmt.Sprintf(":%d", global.GVA_CONFIG.System.Addr)
	s := initServer(address, Router)
	// 保证文本顺序输出
	// In order to ensure that the text order output can be deleted
	time.Sleep(10 * time.Microsecond)
	logger.Info("server run success on ", zap.String("address", address))

	fmt.Printf(`
	欢迎使用 livefind
	默认自动化文档地址:http://127.0.0.1%s/swagger/index.html
`, address)

  go func() {
    if err := s.ListenAndServe(); err != nil && err != http.ErrServerClosed {
      logger.Fatal("server listen :"+err.Error(), err)
    }
  }()

	// Wait for interrupt signal to gracefully shutdown the server with
	// a timeout of 5 seconds.
	quit := make(chan os.Signal)
	// kill (no param) default send syscanll.SIGTERM
	// kill -2 is syscall.SIGINT
	// kill -9 is syscall. SIGKILL but can"t be catch, so don't need add it
	signal.Notify(quit, syscall.SIGTERM, syscall.SIGQUIT, syscall.SIGINT, syscall.SIGKILL)
	sig := <-quit
	logger.Info("Shutdown Server by " + sig.String())

  ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
  defer cancel()
  if err := s.Shutdown(ctx); err != nil {
    logger.Fatal("Server Shutdown:", err)
  }
  // catching ctx.Done(). timeout of 5 seconds.
  select {
  case <-ctx.Done():
    // 关闭连接
    defer func() {
      err := global.GVA_MONGO.Disconnect(ctx)
      if err != nil {
        logger.Error(err.Error(), err)
      } else {
        logger.Info("Closed MongoDB Server SUCCESS")
      }
    }()
    logger.Info("timeout of 5 seconds.")
  }
  logger.Info("Server exiting")
}
